﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace SpellEditor
{
    public partial class frmMain : Form
    {
        private string baseTitle = "Shin Spell Editor";
        MemoryStream memCopy;
        DataTable dtSpells = new DataTable();
        string openedPath;
        Dictionary<int, SpellEntry> spellBook = new Dictionary<int, SpellEntry>();
        SpellEntry currentSpell;
        bool IsPendingSpellChanges;
        int lastSpellSelectedComboboxIndex = -1;


        public frmMain()
        {
            InitializeComponent();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();

        }

        private void aboutShinSpellEditorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("This was written by Shin Noir for usage with EQEmulator", "About");
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.ShowDialog();
        }
        
        private void frmMain_Drag_Enter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
        }

        private void frmMain_Drag_Drop(object sender, DragEventArgs e)
        {
             string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
             foreach (string file in files)
             {
                 if (OpenFile(file)) return;
             }

        }

        private void DisplayElements(bool state)
        {
            cmbSpell.Visible = state;
            lblDropLocationLabel.Visible = !state;
            grpSpell.Visible = state;
        }

        private bool OpenFile(string path)
        {
            if (Path.GetFileName(path) != "spells_us.txt") return false;
            MemoryStream inMemoryCopy = new MemoryStream();
            try
            {
                using (FileStream fs = File.OpenRead(path))
                {
                    fs.CopyTo(inMemoryCopy);
                }
                if (memCopy != null) memCopy.Flush();
                memCopy = inMemoryCopy;
                DisplayElements(true);
                
                openedPath = path;
                Console.WriteLine("Opened " + path);
                LoadAllSpells();
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return false;
        }

        private void CloseFile()
        {
            DisplayElements(false);
            memCopy.Flush();
            openedPath = "";
        }

        private void LoadAllSpells()
        {
            dtSpells.Rows.Clear();
            spellBook.Clear();
            Console.WriteLine("Loading spell");
            Console.WriteLine(memCopy.Length);
            toolStripProgressBar1.Maximum = (int)memCopy.Length;
            int x = 0;
            string[] chunks;
            int spellID;
            SpellEntry spellEntry;
            lastSpellSelectedComboboxIndex = -1;
            using (var reader = new StreamReader(openedPath))
            {
                toolStripStatusLabel1.Text = "Loading spells...";
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    toolStripProgressBar1.Value = (int)reader.BaseStream.Position;
                    Application.DoEvents();
                    chunks = line.Split('^');
                    spellID = System.Int32.Parse(chunks[0]);
                    //if (!spellBook.ContainsKey(spellID)) spellEntry = new SpellEntry(chunks);
                    spellBook[spellID] = new SpellEntry(chunks);
                    spellEntry = spellBook[spellID];
                    dtSpells.Rows.Add(spellEntry.name, spellEntry.id);
                    x++;
                    if (x == 10) break;
                }
            }
            toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
            toolStripStatusLabel1.Text = "Editing "+openedPath;
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            this.Text = baseTitle;
            DisplayElements(false);
            dtSpells.Columns.Add("ID");
            dtSpells.Columns.Add("Name");
            cmbSpell.DataSource = dtSpells;
            cmbSpell.DisplayMember = "Name";
            cmbSpell.ValueMember = "ID";
            cmbSpell.DrawMode = DrawMode.OwnerDrawFixed;
            cmbSpell.DrawItem += delegate(object cmb, DrawItemEventArgs args)
            {
                // Draw the default background
                args.DrawBackground();

                // The ComboBox is bound to a DataTable,
                // so the items are DataRowView objects.
                DataRowView drv = (DataRowView)this.cmbSpell.Items[args.Index];

                // Retrieve the value of each column.
                string id = drv["id"].ToString();
                string name = drv["name"].ToString();

                // Get the bounds for the first column
                Rectangle r1 = args.Bounds;
                r1.Width /= 2;

                // Draw the text on the first column
                using (SolidBrush sb = new SolidBrush(args.ForeColor))
                {
                    args.Graphics.DrawString(id, args.Font, sb, r1);
                }

                // Draw a line to isolate the columns 
                using (Pen p = new Pen(Color.Black))
                {
                    args.Graphics.DrawLine(p, r1.Right, 0, r1.Right, r1.Bottom);
                }

                // Get the bounds for the second column
                Rectangle r2 = args.Bounds;
                r2.X = args.Bounds.Width / 2;
                r2.Width /= 2;

                // Draw the text on the second column
                using (SolidBrush sb = new SolidBrush(args.ForeColor))
                {
                    args.Graphics.DrawString(name, args.Font, sb, r2);
                }
            };

        }

        private void statusStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void LoadSpell(int spellID)
        {
            
            if (!spellBook.ContainsKey(spellID))
            {
                MessageBox.Show("Invalid SpellID: " + spellID);
                return;
            }            
            currentSpell = spellBook[spellID];
            txtIcon.Text = currentSpell.icon;
            txtName.Text = currentSpell.name;

            if (spellIconList.Images.ContainsKey(currentSpell.icon+".png"))
            {
                picSpellIcon.Image = spellIconList.Images[currentSpell.icon+".png"];
            }
            this.Text = baseTitle;
            IsPendingSpellChanges = false;
        }

        private void SaveSpellChanges()
        {
            currentSpell.name = txtName.Text;
            currentSpell.icon = txtIcon.Text;
            Console.WriteLine("Saved spell changes");
            IsPendingSpellChanges = false;
            this.Text = baseTitle;
        }

        private void cmbSpell_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lastSpellSelectedComboboxIndex == cmbSpell.SelectedIndex) return;
            if (lastSpellSelectedComboboxIndex != -1 && lastSpellSelectedComboboxIndex != cmbSpell.SelectedIndex)
            {
                if (IsPendingSpellChanges) 
                {
                    DialogResult dr = MessageBox.Show("Save spell changes before changing to another spell?", "Save before changing spell?", MessageBoxButtons.YesNoCancel);
                    if (dr == System.Windows.Forms.DialogResult.Yes) SaveSpellChanges();
                    if (dr == System.Windows.Forms.DialogResult.Cancel)
                    {
                        cmbSpell.SelectedIndex = lastSpellSelectedComboboxIndex;
                        return;
                    }
                    if (dr == System.Windows.Forms.DialogResult.No)
                    {

                    }
                }
            }
            lastSpellSelectedComboboxIndex = cmbSpell.SelectedIndex;
            Console.WriteLine("Selected "+cmbSpell.Text);
            LoadSpell(System.Int32.Parse(cmbSpell.Text));
        }

        private void txtName_TextChanged(object sender, EventArgs e)
        {
            IsPendingSpellChanges = true;
            this.Text = baseTitle + "*";
            Console.WriteLine("Changes.");
        }

        void frmMain_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            if (IsPendingSpellChanges)
            {
                DialogResult dr = MessageBox.Show("Save spell changes before exiting?", "Save before exit?", MessageBoxButtons.YesNoCancel);
                if (dr == System.Windows.Forms.DialogResult.Yes) SaveSpellChanges();
                if (dr == System.Windows.Forms.DialogResult.Cancel)
                {
                    e.Cancel = true;
                    return;
                }
                if (dr == System.Windows.Forms.DialogResult.No)
                {

                }
            }
        }

        private void txtIcon_TextChanged(object sender, EventArgs e)
        {
            IsPendingSpellChanges = true;
            this.Text = baseTitle + "*";
        }
    }
}
